import React, { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
import { connect, useDispatch } from 'umi';
import { message, Tree, Checkbox, Divider, Spin } from 'antd';
import styles from './index.less';

const CheckboxGroup = Checkbox.Group;

const Page = (props) => {
  const { authActManageModel, roleCode, refInstance, appCodeOfSelect } = props;
  const { resourceTree = [], resourceOfRole, resourceList = [] } = authActManageModel;
  const dispatch = useDispatch();
  const [spinning, setSpinning] = useState(false);
  const [indeterminate, setIndeterminate] = useState(false);
  const [checkedList, setCheckedList] = useState([]);
  const [plainOptions, setPlainOptions] = useState([]);
  const [checkAll, setCheckAll] = useState(false);
  // 记录所有操作角色资源
  const [editRoleResource, setEditRoleResource] = useState({});
  const [selectedKeys, setSelectedKeys] = useState([]);
  const [checkedKeys, setCheckedKeys] = useState([]);

  useImperativeHandle(refInstance, () => ({
    getRoleResourceData: () => editRoleResource,
    setEditRoleResourceByCode,
  }));

  useEffect(() => {
    if (!appCodeOfSelect) return;
    // 获取全量那个资源
    getResourceTree();
    return () => {};
  }, [appCodeOfSelect]);

  useEffect(() => {
    setCheckedKeys(resourceList.map((r) => String(r.resourceId)));
    return () => {};
  }, [resourceList]);

  useEffect(() => {
    if (!roleCode) {
      setEditRoleResource({});
      setCheckedKeys([]);
      // 清空动作
      setPlainOptions([]);
      setCheckedList([]);
      setIndeterminate(false);
      setCheckAll(false);
      setSelectedKeys([]);
      return;
    }
    if (editRoleResource.roleCode || !appCodeOfSelect) return;
    // 获取角色资源权限
    getAuthByRoleCode();
    return () => {};
  }, [roleCode, appCodeOfSelect]);

  useEffect(() => {
    setSpinning(false);
    if (!roleCode) return;
    // 多个角色变更改成一个角色变更，切换角色后，操作记录清空
    // setEditRoleResource({ ...editRoleResource, [roleCode]: resourceOfRole });
    setEditRoleResource({ [roleCode]: resourceOfRole });
    // 清空动作
    // setPlainOptions([]);
    // setCheckedList([]);
    // setIndeterminate(false);
    // setCheckAll(false);
    // 判断已有动作权限
    if (selectedKeys.length === 0) return;
    const resource = resourceOfRole[selectedKeys[0]];
    if (resource && resource.actionList) {
      const checkKeys = resource.actionList.map((d) => d.id);
      setCheckedList(checkKeys);
      setCheckAll(checkKeys.length === plainOptions.length);
      setIndeterminate(checkKeys.length !== 0 && checkKeys.length !== plainOptions.length);
    } else {
      setCheckedList([]);
      setIndeterminate(false);
      setCheckAll(false);
    }
    return () => {};
  }, [resourceOfRole]);

  const setEditRoleResourceByCode = (code, obj) => {
    setEditRoleResource({ [code]: obj });
    // setEditRoleResource({ ...editRoleResource, [code]: obj });
  };

  const getAuthByRoleCode = () => {
    setSpinning(true);
    dispatch({
      type: 'authActManageModel/getAuthByRoleCode',
      payload: { roleCode, appCode: appCodeOfSelect },
    });
  };

  const getResourceTree = () => {
    dispatch({
      type: 'authActManageModel/getResourceTree',
      payload: { appCode: appCodeOfSelect },
    });
  };
  // 树节点选中项变更事件 key:resourceId
  const onSelect = (fSelectedKeys, e) => {
    if (fSelectedKeys.length === 0) {
      // 无选中节点
      setSelectedKeys([]);
      setPlainOptions([]);
      setCheckedList([]);
      setIndeterminate(false);
      return;
    }
    // 判断当前节点是否复选框选中
    if (checkedKeys.indexOf(fSelectedKeys[0]) === -1) {
      message.warning('请先勾选当前资源！');
      return;
    }
    setSelectedKeys(fSelectedKeys);
    // 设置资源全部动作
    console.log(e);
    const plainOptions = (e.node.actionInfoList || []).map((d) => ({
      ...d,
      label: d.actionName,
      value: d.id,
    }));
    setPlainOptions(plainOptions);
    if (!editRoleResource[roleCode]) return;
    // 判断已有动作权限
    const resource = editRoleResource[roleCode][fSelectedKeys[0]];
    if (resource && resource.actionList) {
      const checkKeys = resource.actionList.map((d) => d.id);
      setCheckedList(checkKeys);
      setCheckAll(checkKeys.length === plainOptions.length);
      setIndeterminate(checkKeys.length !== 0 && checkKeys.length !== plainOptions.length);
    } else {
      setCheckedList([]);
      setIndeterminate(false);
      setCheckAll(false);
    }
  };
  // 复选框选中
  const onCheck = (checkedKeys, e) => {
    console.log(checkedKeys);
    if (!roleCode) {
      message.warning('请先选择角色');
      return;
    }
    // 根据复选框的值变更编辑资源节点
    const newRes = { ...editRoleResource[roleCode] };
    if (e.checked) {
      newRes[e.node.key] = {
        resourceCode: e.node.code,
        resourceId: e.node.key,
        resourceName: e.node.title,
        actionList: [],
      };
    } else {
      delete newRes[e.node.key];
      // 取消选中时，如果正在操作当前资源动作，则清空动作
      if (e.node.key === selectedKeys[0]) {
        // 动作复选框重置
        setPlainOptions([]);
        setCheckedList([]);
        setIndeterminate(false);
        setCheckAll(false);
      }
    }
    setEditRoleResource({ ...editRoleResource, [roleCode]: newRes });
    setCheckedKeys(checkedKeys.checked);
  };
  // 动作复选框变更
  const onChange = (list) => {
    setCheckedList(list);
    setIndeterminate(!!list.length && list.length < plainOptions.length);
    setCheckAll(list.length === plainOptions.length);
    // 变更当前角色操作变更资源
    if (editRoleResource[roleCode]) {
      const tempResActions = plainOptions
        .filter((p) => list?.indexOf(p.value) !== -1)
        .map((p) => ({
          id: p.id,
          actionCode: p.actionCode,
          actionName: p.actionName,
        }));
      const tempObj = {
        ...editRoleResource[roleCode][selectedKeys[0]],
        actionList: tempResActions,
      };
      const roleObj = { ...editRoleResource[roleCode], [selectedKeys[0]]: tempObj };
      setEditRoleResource({ ...editRoleResource, [roleCode]: roleObj });
    }
  };
  // 全选事件
  const onCheckAllChange = (e) => {
    setCheckedList(e.target.checked ? plainOptions.map((d) => d.value) : []);
    setIndeterminate(false);
    setCheckAll(e.target.checked);
    // 变更当前角色操作变更资源
    if (editRoleResource[roleCode]) {
      let tempObj = {};
      if (e.target.checked) {
        tempObj = {
          ...editRoleResource[roleCode][selectedKeys[0]],
          actionList: plainOptions.map((p) => ({
            id: p.id,
            actionCode: p.actionCode,
            actionName: p.actionName,
          })),
        };
      } else {
        tempObj = {
          ...editRoleResource[roleCode][selectedKeys[0]],
          actionList: [],
        };
      }
      const roleObj = { ...editRoleResource[roleCode], [selectedKeys[0]]: tempObj };
      setEditRoleResource({ ...editRoleResource, [roleCode]: roleObj });
    }
  };

  const renderTree = (treeData) => {
    return treeData.map((res) => {
      if (res.children.length > 0) {
        return (
          <Tree.TreeNode {...res} checkable={false} selectable={false}>
            {renderTree(res.children)}
          </Tree.TreeNode>
        );
      }
      return <Tree.TreeNode {...res} checkable={true} selectable={true} />;
    });
  };

  return (
    <div className={styles.root}>
      <div className={styles.menuTitleWrapper}>
        <span className={styles.title}>多级资源</span>
      </div>
      <Spin spinning={spinning}>
        <div className={styles.menuTable}>
          {/* <Tree
            className={styles.left}
            showLine={true}
            defaultExpandedKeys={[]}
            selectedKeys={selectedKeys}
            onSelect={onSelect}
            checkable
            onCheck={onCheck}
            checkStrictly
            checkedKeys={checkedKeys}
            treeData={resourceTree}
          /> */}
          <Tree
            className={styles.left}
            showLine={true}
            defaultExpandedKeys={[]}
            selectedKeys={selectedKeys}
            onSelect={onSelect}
            checkable
            onCheck={onCheck}
            checkStrictly
            checkedKeys={checkedKeys}
            treeData={resourceTree}
          >
            {renderTree(resourceTree)}
          </Tree>
          <div className={styles.right}>
            <Checkbox indeterminate={indeterminate} onChange={onCheckAllChange} checked={checkAll}>
              全选
            </Checkbox>
            <Divider />
            <CheckboxGroup options={plainOptions} value={checkedList} onChange={onChange} />
          </div>
        </div>
      </Spin>
    </div>
  );
};

// export default connect((state) => state)(forwardRef(Page));
const Component = connect((state) => state)(Page);
export default forwardRef((props, ref) => <Component {...props} refInstance={ref} />);
